home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994 November: Tool Chest / Dev.CD Nov 94.toast / Tool Chest / Development Tools & Languages / • Other Platforms / PCCTS / antlr / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-14  |  27.8 KB  |  1,131 lines  |  [TEXT/MPS ]

  1. /*
  2.  * main.c -- main program for PCCTS ANTLR.
  3.  *
  4.  * $Id: main.c,v 1.9 1994/08/29 20:16:14 parrt Exp parrt $
  5.  * $Revision: 1.9 $
  6.  *
  7.  * SOFTWARE RIGHTS
  8.  *
  9.  * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
  10.  * Set (PCCTS) -- PCCTS is in the public domain.  An individual or
  11.  * company may do whatever they wish with source code distributed with
  12.  * PCCTS or the code generated by PCCTS, including the incorporation of
  13.  * PCCTS, or its output, into commerical software.
  14.  * 
  15.  * We encourage users to develop software with PCCTS.  However, we do ask
  16.  * that credit is given to us for developing PCCTS.  By "credit",
  17.  * we mean that if you incorporate our source code into one of your
  18.  * programs (commercial product, research project, or otherwise) that you
  19.  * acknowledge this fact somewhere in the documentation, research report,
  20.  * etc...  If you like PCCTS and have developed a nice tool with the
  21.  * output, please mention that you developed it using PCCTS.  In
  22.  * addition, we ask that this header remain intact in our source code.
  23.  * As long as these guidelines are kept, we expect to continue enhancing
  24.  * this system and expect to make other tools available as they are
  25.  * completed.
  26.  *
  27.  * ANTLR 1.23
  28.  * Terence Parr
  29.  * Parr Research Corporation
  30.  * with Purdue University and AHPCRC, University of Minnesota
  31.  * 1989-1994
  32.  */
  33.  
  34. #include <stdio.h>
  35. #ifdef __cplusplus
  36. #ifndef __STDC__
  37. #define __STDC__
  38. #endif
  39. #endif
  40. #include "stdpccts.h"
  41.  
  42. #define MAX_INT_STACK 50
  43. static int istack[MAX_INT_STACK];        /* Int stack */
  44. static int isp = MAX_INT_STACK;
  45.  
  46. static int DontAcceptFiles = 0;            /* if stdin, don't read files */
  47. static int DontAcceptStdin = 0;            /* if files seen first, don't accept stdin */
  48.  
  49.  
  50.         /* C m d - L i n e  O p t i o n  S t r u c t  &  F u n c s */
  51.  
  52. typedef struct _Opt {
  53.             char *option;
  54.             int  arg;
  55. #ifdef __cplusplus
  56.             void (*process)(...);
  57. #else
  58.             void (*process)();
  59. #endif
  60.             char *descr;
  61.         } Opt;
  62.  
  63. #ifdef __STDC__
  64. extern void ProcessArgs(int, char **, Opt *);
  65. #else
  66. extern void ProcessArgs();
  67. #endif
  68.  
  69. static void
  70. #ifdef __STDC__
  71. pStdin( void )
  72. #else
  73. pStdin( )
  74. #endif
  75. {
  76.     if ( DontAcceptStdin )
  77.     {
  78.         warnNoFL("'-' (stdin) ignored as files were specified first");
  79.         return;
  80.     }
  81.  
  82.     require(NumFiles<MaxNumFiles,"exceeded max # of input files");
  83.     FileStr[NumFiles++] = "stdin";
  84.     DontAcceptFiles = 1;
  85. }
  86.  
  87. static void
  88. #ifdef __STDC__
  89. pFile( char *s )
  90. #else
  91. pFile( s )
  92. char *s;
  93. #endif
  94. {
  95.     if ( *s=='-' ) { warnNoFL( eMsg1("invalid option: '%s'",s) ); return; }
  96.     if ( DontAcceptFiles )
  97.     {
  98.         warnNoFL(eMsg1("file '%s' ignored as '-' (stdin option) was specified first",s));
  99.         return;
  100.     }
  101.  
  102.     require(NumFiles<MaxNumFiles,"exceeded max # of input files");
  103.     FileStr[NumFiles++] = s;
  104.     DontAcceptStdin = 1;
  105. }
  106.  
  107. static void
  108. #ifdef __STDC__
  109. pLLK( char *s, char *t )
  110. #else
  111. pLLK( s, t )
  112. char *s;
  113. char *t;
  114. #endif
  115. {
  116.     LL_k = atoi(t);
  117.     if ( LL_k <= 0 ) {
  118.         warnNoFL("must have at least one token of lookahead (setting to 1)");
  119.         LL_k = 1;
  120.     }
  121. }
  122.  
  123. static void
  124. #ifdef __STDC__
  125. pCk( char *s, char *t )
  126. #else
  127. pCk( s, t )
  128. char *s;
  129. char *t;
  130. #endif
  131. {
  132.     CLL_k = atoi(t);
  133.     if ( CLL_k <= 0 ) {
  134.         warnNoFL("must have at least one token of look-ahead (setting to 1)");
  135.         CLL_k = 1;
  136.     }
  137. }
  138.  
  139. #ifdef __STDC__
  140. static void pCGen(void)    { CodeGen = FALSE; LexGen = FALSE; }
  141. static void pLGen(void)    { LexGen = FALSE; }
  142. static void pTGen(void)    { TraceGen = TRUE; }
  143. static void pSGen(void)    { GenExprSets = FALSE; }
  144. static void pPrt(void)    { PrintOut = TRUE; pCGen(); pLGen(); }
  145. static void pPrtA(void)    { PrintOut = TRUE; PrintAnnotate = TRUE; pCGen(); pLGen(); }
  146. static void pAst(void)    { GenAST = TRUE; }
  147. static void pANSI(void)    { GenANSI = TRUE; }
  148. static void pCr(void)    { GenCR = TRUE; }
  149. static void pCt(void)    { warnNoFL("-ct option is now the default"); }
  150. static void pLI(void)    { GenLineInfo = TRUE; }
  151. static void pFr(char *s, char *t) {RemapFileName = t;}
  152. static void pFe(char *s, char *t) {ErrFileName = t;}
  153. static void pFl(char *s, char *t) {DlgFileName = t;}
  154. static void pFm(char *s, char *t) {ModeFileName = t;}
  155. static void pFt(char *s, char *t) {DefFileName = t;}
  156. static void pE1(void)    { elevel = 1; }
  157. static void pE2(void)    { elevel = 2; }
  158. static void pE3(void)    { elevel = 3; }
  159. static void pEGen(void)    { GenEClasseForRules = 1; }
  160. static void pDL(void)    { DemandLookahead = 1; }
  161. static void pGHdr(void)    { GenStdPccts = 1; }
  162. static void pFHdr(char *s, char *t) { stdpccts = t; pGHdr(); }
  163. static void pW1(void) { WarningLevel = 1; }
  164. static void pW2(void) { WarningLevel = 2; }
  165. static void pCC(void) { GenCC = TRUE; }
  166. #else
  167. static void pCGen()    { CodeGen = FALSE; LexGen = FALSE; }
  168. static void pLGen()    { LexGen = FALSE; }
  169. static void pTGen()    { TraceGen = TRUE; }
  170. static void pSGen()    { GenExprSets = FALSE; }
  171. static void pPrt()        { PrintOut = TRUE; pCGen(); pLGen(); }
  172. static void pPrtA()    { PrintOut = TRUE; PrintAnnotate = TRUE; pCGen(); pLGen(); }
  173. static void pAst()        { GenAST = TRUE; }
  174. static void pANSI()    { GenANSI = TRUE; }
  175. static void pCr()        { GenCR = TRUE; }
  176. static void pCt()        { warnNoFL("-ct option is now the default"); }
  177. static void pLI()        { GenLineInfo = TRUE; }
  178. static void pFr(s,t) char *s, *t; {RemapFileName = t;}
  179. static void pFe(s,t) char *s, *t; {ErrFileName = t;}
  180. static void pFl(s,t) char *s, *t; {DlgFileName = t;}
  181. static void pFm(s,t) char *s, *t; {ModeFileName = t;}
  182. static void pFt(s,t) char *s, *t; {DefFileName = t;}
  183. static void pE1()        { elevel = 1; }
  184. static void pE2()        { elevel = 2; }
  185. static void pE3()        { elevel = 3; }
  186. static void pEGen()    { GenEClasseForRules = 1; }
  187. static void pDL()        { DemandLookahead = 1; }
  188. static void pGHdr()    { GenStdPccts = 1; }
  189. static void pFHdr(s,t) char *s, *t; { stdpccts = t; pGHdr(); }
  190. static void pW1() { WarningLevel = 1; }
  191. static void pW2() { WarningLevel = 2; }
  192. static void pCC() { GenCC = TRUE; }
  193. #endif
  194.  
  195. static void
  196. #ifdef __STDC__
  197. pPre( char *s, char *t )
  198. #else
  199. pPre( s, t )
  200. char *s;
  201. char *t;
  202. #endif
  203. {
  204.     RulePrefix = t;
  205. }
  206.  
  207. static void
  208. #ifdef __STDC__
  209. pOut( char *s, char *t )
  210. #else
  211. pOut( s, t )
  212. char *s;
  213. char *t;
  214. #endif
  215. {
  216.     OutputDirectory = t;
  217. }
  218.  
  219. static void
  220. #ifdef __STDC__
  221. pPred( void )
  222. #else
  223. pPred( )
  224. #endif
  225. {
  226.     warnNoFL("-pr is no longer used (predicates employed if present); see -prc");
  227. /*
  228.     if ( DemandLookahead )
  229.         warnNoFL("-gk conflicts with -pr; -gk turned off");
  230.     DemandLookahead = 0;
  231.     HoistPredicateContext = 0;
  232. */
  233. }
  234.  
  235. static void
  236. #ifdef __STDC__
  237. pPredCtx( char *s, char *t )
  238. #else
  239. pPredCtx(s,t)
  240. char *s;
  241. char *t;
  242. #endif
  243. {
  244.     if ( strcmp(t, "on")==0 ) HoistPredicateContext = 1;
  245.     else if ( strcmp(t, "ON")==0 ) HoistPredicateContext = 1;
  246.     else if ( strcmp(t, "off")==0 ) HoistPredicateContext = 0;
  247.     else if ( strcmp(t, "OFF")==0 ) HoistPredicateContext = 0;
  248.     if ( DemandLookahead )
  249.     {
  250.         warnNoFL("-gk incompatible with semantic predicate usage; -gk turned off");
  251.         DemandLookahead = 0;
  252.     }
  253. }
  254.  
  255. static void
  256. #ifdef __STDC__
  257. pTRes( char *s, char *t )
  258. #else
  259. pTRes( s, t )
  260. char *s;
  261. char *t;
  262. #endif
  263. {
  264.     TreeResourceLimit = atoi(t);
  265.     if ( TreeResourceLimit <= 0 )
  266.     {
  267.         warnNoFL("analysis resource limit (# of tree nodes) must be greater than 0");
  268.         TreeResourceLimit = -1; /* set to no limit */
  269.     }
  270. }
  271.  
  272. Opt options[] = {
  273. #ifdef __cplusplus
  274.     { "-CC", 0, (void (*)(...)) pCC,    "Generate C++ output (default=FALSE)"},
  275.     { "-ck", 1, (void (*)(...)) pCk,    "Set compressed lookahead depth; fast approximate lookahead"},
  276.     { "-cr", 0, (void (*)(...)) pCr,    "Generate cross reference (default=FALSE)"},
  277.     { "-ct", 0, (void (*)(...)) pCt,    "Do not copy tokens in C++ mode (default=to copy)"},*/
  278.     { "-e1", 0, (void (*)(...)) pE1,    "Ambiguities/errors shown in low detail (default)"},
  279.     { "-e2", 0, (void (*)(...)) pE2,    "Ambiguities/errors shown in more detail"},
  280.     { "-e3", 0, (void (*)(...)) pE3,    "Ambiguities/errors shown in excruciating detail"},
  281.     { "-fe", 1, (void (*)(...)) pFe,    "Rename err.c"},
  282.     { "-fh", 1, (void (*)(...)) pFHdr,    "Rename stdpccts.h header (turns on -gh)"},
  283.     { "-fl", 1, (void (*)(...)) pFl,    "Rename lexical output--parser.dlg"},
  284.     { "-fm", 1, (void (*)(...)) pFm,    "Rename mode.h"},
  285.     { "-fr", 1, (void (*)(...)) pFr,    "Rename remap.h"},
  286.     { "-ft", 1, (void (*)(...)) pFt,    "Rename tokens.h"},
  287.     { "-ga", 0, (void (*)(...)) pANSI,    "Generate ANSI-compatible code (default=FALSE)"},
  288.     { "-gc", 0, (void (*)(...)) pCGen,    "Do not generate output parser code (default=FALSE)"},
  289.     { "-gd", 0, (void (*)(...)) pTGen,    "Generate code to trace rule invocation (default=FALSE)"},
  290.     { "-ge", 0, (void (*)(...)) pEGen,    "Generate an error class for each non-terminal (default=FALSE)"},
  291.     { "-gh", 0, (void (*)(...)) pGHdr,    "Generate stdpccts.h for non-ANTLR-generated-files to include"},
  292.     { "-gk", 0, (void (*)(...)) pDL,    "Generate parsers that delay lookahead fetches 'til needed"},
  293.     { "-gl", 0, (void (*)(...)) pLI,    "Generate line info about grammar actions in C parser"},
  294.     { "-gp", 1, (void (*)(...)) pPre,    "Prefix all generated rule functions with a string"},
  295.     { "-gs", 0, (void (*)(...)) pSGen,    "Do not generate sets for token expression lists (default=FALSE)"},
  296.     { "-gt", 0, (void (*)(...)) pAst,    "Generate code for Abstract-Syntax-Trees (default=FALSE)"},
  297.     { "-gx", 0, (void (*)(...)) pLGen,    "Do not generate lexical (dlg-related) files (default=FALSE)"},
  298.     { "-k",  1, (void (*)(...)) pLLK,    "Set full LL(k) lookahead depth (default==1)"},
  299.     { "-o",  1, (void (*)(...)) pOut,    OutputDirectoryOption},
  300.     { "-p",  0, (void (*)(...)) pPrt,    "Print out the grammar w/o actions (default=no)"},
  301.     { "-pa", 0, (void (*)(...)) pPrtA,    "Print out the grammar w/o actions & w/FIRST sets (default=no)"},
  302.     { "-pr",0, (void (*)(...)) pPred,    "no longer used; predicates employed if present"},
  303.     { "-prc", 1, (void (*)(...)) pPredCtx,"Turn on/off computation of context for hoisted predicates"},
  304.        { "-rl", 1, (void (*)(...)) pTRes,    "Limit max # of tree nodes used by grammar analysis"},
  305.     { "-w1", 0, (void (*)(...)) pW1,    "Set the warning level to 1 (default)"},
  306.     { "-w2", 0, (void (*)(...)) pW2,    "Ambiguities yield warnings even if predicates or (...)? block"},
  307.     { "-",   0, (void (*)(...)) pStdin,    "Read grammar from stdin" },
  308.     { "*",   0, (void (*)(...)) pFile,     "" },    /* anything else is a file */
  309. #else
  310.     { "-CC", 0, pCC,    "Generate C++ output (default=FALSE)"},
  311.     { "-cr", 0, pCr,    "Generate cross reference (default=FALSE)"},
  312.     { "-ct", 0, pCt,    "Do not copy tokens in C++ mode (default=to copy)"},
  313.     { "-ck", 1, pCk,    "Set compressed lookahead depth; fast approximate lookahead"},
  314.     { "-e1", 0, pE1,    "Ambiguities/errors shown in low detail (default)"},
  315.     { "-e2", 0, pE2,    "Ambiguities/errors shown in more detail"},
  316.     { "-e3", 0, pE3,    "Ambiguities/errors shown in excrutiating detail"},
  317.     { "-fe", 1, pFe,    "Rename err.c"},
  318.     { "-fh", 1, pFHdr,    "Rename stdpccts.h header (turns on -gh)"},
  319.     { "-fl", 1, pFl,    "Rename lexical output--parser.dlg"},
  320.     { "-fm", 1, pFm,    "Rename mode.h"},
  321.     { "-fr", 1, pFr,    "Rename remap.h"},
  322.     { "-ft", 1, pFt,    "Rename tokens.h"},
  323.     { "-ga", 0, pANSI,    "Generate ANSI-compatible code (default=FALSE)"},
  324.     { "-gc", 0, pCGen,    "Do not generate output parser code (default=FALSE)"},
  325.     { "-gd", 0, pTGen,    "Generate code to trace rule invocation (default=FALSE)"},
  326.     { "-ge", 0, pEGen,    "Generate an error class for each non-terminal (default=FALSE)"},
  327.     { "-gh", 0, pGHdr,    "Generate stdpccts.h for non-ANTLR-generated-files to include"},
  328.     { "-gk", 0, pDL,    "Generate parsers that delay lookahead fetches 'til needed"},
  329.     { "-gl", 0, pLI,    "Generate line info about grammar actions in C parser"},
  330.     { "-gp", 1, pPre,    "Prefix all generated rule functions with a string"},
  331.     { "-gs", 0, pSGen,    "Do not generate sets for token expression lists (default=FALSE)"},
  332.     { "-gt", 0, pAst,    "Generate code for Abstract-Syntax-Trees (default=FALSE)"},
  333.     { "-gx", 0, pLGen,    "Do not generate lexical (dlg-related) files (default=FALSE)"},
  334.     { "-k",  1, pLLK,    "Set full LL(k) lookahead depth (default==1)"},
  335.     { "-o",  1, pOut,    OutputDirectoryOption},
  336.     { "-p",  0, pPrt,    "Print out the grammar w/o actions (default=no)"},
  337.     { "-pa", 0, pPrtA,    "Print out the grammar w/o actions & w/FIRST sets (default=no)"},
  338.     { "-pr",0, pPred,    "no longer used; predicates employed if present"},
  339.     { "-prc", 1, pPredCtx,"Turn on/off computation of context for hoisted predicates"},
  340.        { "-rl", 1, pTRes,    "Limit max # of tree nodes used by grammar analysis"},
  341.     { "-w1", 0, pW1,    "Set the warning level to 1 (default)"},
  342.     { "-w2", 0, pW2,    "Ambiguities yield warnings even if predicates or (...)? block"},
  343.     { "-",   0, pStdin,    "Read grammar from stdin" },
  344.     { "*",   0, pFile,     "" },    /* anything else is a file */
  345. #endif
  346.     { NULL,  0, NULL }
  347. };
  348.  
  349. void readDescr();
  350. void cleanUp();
  351.  
  352. #ifdef __STDC__
  353. static void buildRulePtr( void );
  354. static void help( void );
  355. static void init( void );
  356. static void CompleteTokenSetRefs( void );
  357. static void ensure_no_C_file_collisions(char *);
  358. #else
  359. static void buildRulePtr( );
  360. static void help( );
  361. static void init( );
  362. static void CompleteTokenSetRefs( );
  363. static void ensure_no_C_file_collisions();
  364. #endif
  365.  
  366.                                 /* M a i n */
  367.  
  368. int
  369. #ifdef __STDC__
  370. main( int argc, char *argv[] )
  371. #else
  372. main( argc, argv )
  373. int argc;
  374. char *argv[];
  375. #endif
  376. {
  377.     int i;
  378.     static char EPSTR[] = "[Ep]";
  379.  
  380.     special_inits();
  381.  
  382.     fprintf(stderr, "Antlr parser generator   Version %s   1989-1994\n", Version);
  383.     if ( argc == 1 ) { help(); DIE; }
  384.     ProcessArgs(argc-1, &(argv[1]), options);
  385.  
  386.     /* Fix lookahead depth */
  387.     /* Compressed lookahead must always be larger than or equal to full lookahead */
  388.     if ( CLL_k < LL_k  && CLL_k>0 )
  389.     {
  390.         warnNoFL("must have compressed lookahead >= full LL(k) lookahead (setting -ck to -k)");
  391.         CLL_k = LL_k;
  392.     }
  393.     if ( CLL_k == -1 ) CLL_k = LL_k;
  394.     OutputLL_k = CLL_k;
  395.     if ( ((CLL_k-1)&CLL_k)!=0 ) { /* output ll(k) must be power of 2 */
  396.         int n;
  397.         for(n=1; n<CLL_k; n<<=1) {;}
  398.         OutputLL_k = n;
  399.     }
  400.  
  401.     fpTrans = &(C_Trans[0]);        /* Translate to C Language */
  402.     fpJTrans = &(C_JTrans[0]);
  403.     init();
  404.     lexclass(LexStartSymbol);
  405.  
  406.     readDescr();
  407.     LastTokenCounted = TokenNum;
  408.     RemapForcedTokens();
  409.     if ( CannotContinue ) {cleanUp(); DIE;}
  410.     if ( GenCC && no_classes_found ) fatal("required grammar class not found (exiting...)");
  411.     if ( WarningLevel>1 && HdrAction == NULL )
  412.        warnNoFL("no #header action was found");
  413.  
  414.     EpToken = addTname(EPSTR);        /* add imaginary token epsilon */
  415.     set_orel(EpToken, &imag_tokens);
  416.  
  417.     /* this won't work for hand-built scanners since EofToken is not
  418.      * known.  Forces EOF to be token type 1.
  419.      */
  420.     set_orel(EofToken, &imag_tokens);
  421.  
  422.     set_size(NumWords(TokenNum-1));
  423.  
  424.     /* compute the set of all known token types 
  425.      * It represents the set of tokens from 1 to last_token_num + the
  426.      * reserved positions above that (if any).  Don't include the set of
  427.      * imaginary tokens such as the token/error classes or EOF.
  428.      */
  429.     {
  430.         set a;
  431.         a = set_dup(reserved_positions);
  432.         for (i=1; i<TokenNum; i++) { set_orel(i, &a); }
  433.         all_tokens = set_dif(a, imag_tokens);
  434.         set_free(a);
  435.     }
  436.  
  437.     ComputeTokSets();
  438.     CompleteTokenSetRefs();
  439.  
  440.     if ( CodeGen ) genDefFile();    /* create tokens.h */
  441.     if ( LexGen ) genLexDescr();    /* create parser.dlg */
  442.  
  443.     if ( GenStdPccts )
  444.     {
  445.         FILE *f = fopen(OutMetaName(stdpccts), "w");
  446.         if ( f==NULL ) {warnNoFL( eMsg1("can't create %s",OutMetaName(stdpccts)) );}
  447.         else
  448.         {
  449.             special_fopen_actions(OutMetaName(stdpccts));
  450.             genStdPCCTSIncludeFile(f);
  451.             fclose(f);
  452.         }
  453.     }
  454.  
  455.     buildRulePtr();                    /* create mapping from rule # to RuleBlk junction */
  456.     ComputeErrorSets();
  457.     FoLink( (Node *)SynDiag );        /* add follow links to end of all rules */
  458.     
  459.     if ( GenCR ) GenCrossRef( SynDiag );
  460.  
  461.     if ( CodeGen )
  462.     {
  463.         if ( SynDiag == NULL )
  464.         {
  465.             warnNoFL("no grammar description recognized");
  466.             cleanUp();
  467.             DIE;
  468.         }
  469.         else if ( !GenCC ) {
  470.             ErrFile = fopen(OutMetaName(ErrFileName), "w");
  471.             require(ErrFile != NULL, "main: can't open err file");
  472.             special_fopen_actions(OutMetaName(ErrFileName));
  473.             NewSetWd();
  474.             GenErrHdr();
  475.             TRANS(SynDiag);            /* Translate to the target language */
  476.             DumpSetWd();
  477.             fclose( ErrFile );
  478.         }
  479.         else {
  480.             strcpy(Parser_h_Name, CurrentClassName);
  481.             strcat(Parser_h_Name, ".h");
  482.             strcpy(Parser_c_Name, CurrentClassName);
  483.             strcat(Parser_c_Name, CPP_FILE_SUFFIX);
  484.             ensure_no_C_file_collisions(Parser_c_Name);
  485.             Parser_h = fopen(OutMetaName(Parser_h_Name), "w");
  486.             require(Parser_h != NULL, "main: can't open class Parserx.h file");
  487.             special_fopen_actions(OutMetaName(Parser_h_Name));
  488.             Parser_c = fopen(OutMetaName(Parser_c_Name), "w");
  489.             require(Parser_c != NULL, "main: can't open class Parserx.c file");
  490.             special_fopen_actions(OutMetaName(Parser_c_Name));
  491.             GenParser_h_Hdr();
  492.             GenParser_c_Hdr();
  493.             NewSetWd();
  494.             TRANS(SynDiag);            /* Translate to the target language */
  495.             DumpSetWd();
  496.             GenRuleMemberDeclarationsForCC(Parser_h, SynDiag);
  497.             /* Dump class members */
  498.             if ( class_actions != NULL )
  499.             {
  500.                 ListNode *p;
  501.                 for (p = class_actions->next; p!=NULL; p=p->next)
  502.                 {
  503.                     UserAction *ua = (UserAction *)p->elem;
  504.                     dumpAction( ua->action, Parser_h, 0, ua->file, ua->line, 1);
  505.                 }
  506.             }
  507.             fprintf(Parser_h, "};\n");
  508.             fclose( Parser_h );
  509.             fclose( Parser_c );
  510.         }
  511.     }
  512.  
  513.     if ( PrintOut )
  514.     {
  515.         if ( SynDiag == NULL ) {warnNoFL("no grammar description recognized");}
  516.         else PRINT(SynDiag);
  517.     }
  518.  
  519.     GenRemapFile();                    /* create remap.h */
  520.  
  521.     cleanUp();
  522. #ifdef VAXC
  523.     return 1;               /* report all is well for make etc... */
  524. #else
  525.     return 0;               /* report all is well for make etc... */
  526. #endif
  527. }
  528.  
  529. static void
  530. #ifdef __STDC__
  531. init( void )
  532. #else
  533. init( )
  534. #endif
  535. {
  536.     Tname = newHashTable();
  537.     Rname = newHashTable();
  538.     Fcache = newHashTable();
  539.     Tcache = newHashTable();
  540.     reserved_positions = empty;
  541.     all_tokens = empty;
  542.     imag_tokens = empty;
  543.     TokenStr = (char **) calloc(TSChunk, sizeof(char *));
  544.     require(TokenStr!=NULL, "main: cannot allocate TokenStr");
  545.     FoStack = (int **) calloc(CLL_k+1, sizeof(int *));
  546.     require(FoStack!=NULL, "main: cannot allocate FoStack");
  547.     FoTOS = (int **) calloc(CLL_k+1, sizeof(int *));
  548.     require(FoTOS!=NULL, "main: cannot allocate FoTOS");
  549.     Cycles = (ListNode **) calloc(CLL_k+1, sizeof(ListNode *));
  550.     require(Cycles!=NULL, "main: cannot allocate Cycles List");
  551. }
  552.  
  553. static void
  554. #ifdef __STDC__
  555. help( void )
  556. #else
  557. help( )
  558. #endif
  559. {
  560.     Opt *p = options;
  561.     fprintf(stderr, "antlr [options] f1 f2 ... fn\n");
  562.     while ( *(p->option) != '*' )
  563.     {
  564.         fprintf(stderr, "\t%-4s %s   %s\n",
  565.                         p->option,
  566.                         (p->arg)?"___":"   ",
  567.                         p->descr);
  568.         p++;
  569.     }
  570. }
  571.  
  572. /* The RulePtr array is filled in here.  RulePtr exists primarily
  573.  * so that sets of rules can be maintained for the FOLLOW caching
  574.  * mechanism found in rJunc().  RulePtr maps a rule num from 1 to n
  575.  * to a pointer to its RuleBlk junction where n is the number of rules.
  576.  */
  577. static void
  578. #ifdef __STDC__
  579. buildRulePtr( void )
  580. #else
  581. buildRulePtr( )
  582. #endif
  583. {
  584.     int r=1;
  585.     Junction *p  = SynDiag;
  586.     RulePtr = (Junction **) calloc(NumRules+1, sizeof(Junction *));
  587.     require(RulePtr!=NULL, "cannot allocate RulePtr array");
  588.     
  589.     while ( p!=NULL )
  590.     {
  591.         require(r<=NumRules, "too many rules???");
  592.         RulePtr[r++] = p;
  593.         p = (Junction *)p->p2;
  594.     }
  595. }
  596.  
  597. void
  598. #ifdef __STDC__
  599. dlgerror(char *s)
  600. #else
  601. dlgerror(s)
  602. char *s;
  603. #endif
  604. {
  605.     fprintf(stderr, ErrHdr, FileStr[CurFile], zzline);
  606.     fprintf(stderr, " lexical error: %s (text was '%s')\n",
  607.                     ((s == NULL) ? "Lexical error" : s), zzlextext);
  608. }
  609.  
  610. void
  611. #ifdef __STDC__
  612. readDescr( void )
  613. #else
  614. readDescr( )
  615. #endif
  616. {
  617.     zzerr = dlgerror;
  618.     input = NextFile();
  619.     if ( input==NULL ) fatal("No grammar description found (exiting...)");
  620.     ANTLR(grammar(), input);
  621. }
  622.  
  623. FILE *
  624. #ifdef __STDC__
  625. NextFile( void )
  626. #else
  627. NextFile( )
  628. #endif
  629. {
  630.     FILE *f;
  631.  
  632.     for (;;)
  633.     {
  634.         CurFile++;
  635.         if ( CurFile >= NumFiles ) return(NULL);
  636.         if ( strcmp(FileStr[CurFile],"stdin") == 0 ) return stdin;
  637.         f = fopen(FileStr[CurFile], "r");
  638.         if ( f == NULL )
  639.         {
  640.             warnNoFL( eMsg1("file %s doesn't exist; ignored", FileStr[CurFile]) );
  641.         }
  642.         else
  643.         {
  644.             return(f);
  645.         }
  646.     }
  647. }
  648.  
  649. /*
  650.  * Return a string corresponding to the output file name associated
  651.  * with the input file name passed in.
  652.  *
  653.  * Observe the following rules:
  654.  *
  655.  *        f.e        --> f".c"
  656.  *        f        --> f".c"
  657.  *        f.        --> f".c"
  658.  *        f.e.g    --> f.e".c"
  659.  *
  660.  * Where f,e,g are arbitrarily long sequences of characters in a file
  661.  * name.
  662.  *
  663.  * In other words, if a ".x" appears on the end of a file name, make it
  664.  * ".c".  If no ".x" appears, append ".c" to the end of the file name.
  665.  *
  666.  * C++ mode using .C not .c.
  667.  *
  668.  * Use malloc() for new string.
  669.  */
  670. char *
  671. #ifdef __STDC__
  672. outname( char *fs )
  673. #else
  674. outname( fs )
  675. char *fs;
  676. #endif
  677. {
  678.     static char buf[MaxFileName+1];
  679.     char *p;
  680.     require(fs!=NULL&&*fs!='\0', "outname: NULL filename");
  681.  
  682.     p = buf;
  683.     strcpy(buf, fs);
  684.     while ( *p != '\0' )  {p++;}            /* Stop on '\0' */
  685.     while ( *p != '.' && p != buf ) {--p;}    /* Find '.' */
  686.     if ( p != buf ) *p = '\0';                /* Found '.' */
  687.     require(strlen(buf) + 2 < MaxFileName, "outname: filename too big");
  688.     if ( GenCC ) strcat(buf, CPP_FILE_SUFFIX);
  689.     else strcat(buf, ".c");
  690.     return( buf );
  691. }
  692.  
  693. void
  694. #ifdef __STDC__
  695. fatalFL( char *err_, char *f, int l )
  696. #else
  697. fatalFL( err_, f, l )
  698. char *err_;
  699. char *f;
  700. int l;
  701. #endif
  702. {
  703.     fprintf(stderr, ErrHdr, f, l);
  704.     fprintf(stderr,    " %s\n", err_);
  705.     cleanUp();
  706.     exit(1);
  707. }
  708.  
  709. void
  710. #ifdef __STDC__
  711. fatal_intern( char *err_, char *f, int l )
  712. #else
  713. fatal_intern( err_, f, l )
  714. char *err_;
  715. char *f;
  716. int l;
  717. #endif
  718. {
  719.     fprintf(stderr, ErrHdr, f, l);
  720.     fprintf(stderr,    " #$%%*&@# internal error: %s\n", err_);
  721.     fprintf(stderr, ErrHdr, f, l);
  722.     fprintf(stderr, " [complain to nearest government official\n");
  723.     fprintf(stderr, ErrHdr, f, l);
  724.     fprintf(stderr, "  or send hate-mail to parrt@acm.org;\n");
  725.     fprintf(stderr, ErrHdr, f, l);
  726.     fprintf(stderr, "  please pray to the ``bug'' gods that there is a trival fix.]\n");
  727.     cleanUp();
  728.     exit(1);
  729. }
  730.  
  731. void
  732. #ifdef __STDC__
  733. cleanUp( void )
  734. #else
  735. cleanUp( )
  736. #endif
  737. {
  738.     if ( DefFile != NULL) fclose( DefFile );
  739. }
  740.  
  741. /* sprintf up to 3 strings */
  742. char *
  743. #ifdef __STDC__
  744. eMsg3( char *s, char *a1, char *a2, char *a3 )
  745. #else
  746. eMsg3( s, a1, a2, a3 )
  747. char *s;
  748. char *a1;
  749. char *a2;
  750. char *a3;
  751. #endif
  752. {
  753.     static char buf[250];            /* DANGEROUS as hell !!!!!! */
  754.     
  755.     sprintf(buf, s, a1, a2, a3);
  756.     return( buf );
  757. }
  758.  
  759. /* sprintf a decimal */
  760. char *
  761. #ifdef __STDC__
  762. eMsgd( char *s, int d )
  763. #else
  764. eMsgd( s, d )
  765. char *s;
  766. int d;
  767. #endif
  768. {
  769.     static char buf[250];            /* DANGEROUS as hell !!!!!! */
  770.     
  771.     sprintf(buf, s, d);
  772.     return( buf );
  773. }
  774.  
  775. void
  776. #ifdef __STDC__
  777. s_fprT( FILE *f, set e )
  778. #else
  779. s_fprT( f, e )
  780. FILE *f;
  781. set e;
  782. #endif
  783. {
  784.     register unsigned *p;
  785.     unsigned *q;
  786.  
  787.     if ( set_nil(e) ) return;
  788.     if ( (q=p=set_pdq(e)) == NULL ) fatal_internal("Can't alloc space for set_pdq");
  789.     fprintf(f, "{");
  790.     while ( *p != nil )
  791.     {
  792.         fprintf(f, " %s", TerminalString(*p));
  793.         p++;
  794.     }
  795.     fprintf(f, " }");
  796.     free((char *)q);
  797. }
  798.  
  799. /* Return the token name or regular expression for a token number. */
  800. char *
  801. #ifdef __STDC__
  802. TerminalString( int token )
  803. #else
  804. TerminalString( token )
  805. int token;
  806. #endif
  807. {
  808.     int j;
  809.  
  810.     /* look in all lexclasses for the token */
  811.     if ( TokenString(token) != NULL ) return TokenString(token);
  812.     for (j=0; j<NumLexClasses; j++)
  813.     {
  814.         lexmode(j);
  815.         if ( ExprString(token) != NULL ) return ExprString(token);
  816.     }
  817.     require(j<NumLexClasses, eMsgd("No label or expr for token %d",token));
  818.     return "invalid";
  819. }
  820.  
  821.                     /* S i m p l e  I n t  S t a c k */
  822.  
  823. void
  824. #ifdef __STDC__
  825. pushint( int i )
  826. #else
  827. pushint( i )
  828. int i;
  829. #endif
  830. {
  831.     require(isp>0, "pushint: stack overflow");
  832.     istack[--isp] = i;
  833. }
  834.  
  835. int
  836. #ifdef __STDC__
  837. popint( void )
  838. #else
  839. popint( )
  840. #endif
  841. {
  842.     require(isp<MAX_INT_STACK, "popint: stack underflow");
  843.     return istack[isp++];
  844. }
  845.  
  846. int
  847. #ifdef __STDC__
  848. istacksize( void )
  849. #else
  850. istacksize( )
  851. #endif
  852. {
  853.     return MAX_INT_STACK-isp;
  854. }
  855.  
  856. void
  857. #ifdef __STDC__
  858. istackreset( void )
  859. #else
  860. istackreset( )
  861. #endif
  862. {
  863.     isp = MAX_INT_STACK;
  864. }
  865.  
  866. int
  867. #ifdef __STDC__
  868. istackempty( void )
  869. #else
  870. istackempty( )
  871. #endif
  872. {
  873.     return isp==MAX_INT_STACK;
  874. }
  875.  
  876. int
  877. #ifdef __STDC__
  878. topint( void )
  879. #else
  880. topint( )
  881. #endif
  882. {
  883.     require(isp<MAX_INT_STACK, "topint: stack underflow");
  884.     return istack[isp];
  885. }
  886.  
  887. void
  888. #ifdef __STDC__
  889. ProcessArgs( int argc, char **argv, Opt *options )
  890. #else
  891. ProcessArgs( argc, argv, options )
  892. int argc;
  893. char **argv;
  894. Opt *options;
  895. #endif
  896. {
  897.     Opt *p;
  898.     require(argv!=NULL, "ProcessArgs: command line NULL");
  899.  
  900.     while ( argc-- > 0 )
  901.     {
  902.         p = options;
  903.         while ( p->option != NULL )
  904.         {
  905.             if ( strcmp(p->option, "*") == 0 ||
  906.                  strcmp(p->option, *argv) == 0 )
  907.             {
  908.                 if ( p->arg )
  909.                 {
  910.                     (*p->process)( *argv, *(argv+1) );
  911.                     argv++;
  912.                     argc--;
  913.                 }
  914.                 else
  915.                     (*p->process)( *argv );
  916.                 break;
  917.             }
  918.             p++;
  919.         }
  920.         argv++;
  921.     }
  922. }
  923.  
  924. /* Go back into the syntax diagram and compute all meta tokens; i.e.
  925.  * turn all '.', ranges, token class refs etc... into actual token sets
  926.  */
  927. static void
  928. CompleteTokenSetRefs()
  929. {
  930.     ListNode *p;
  931.  
  932.     if ( MetaTokenNodes==NULL ) return;
  933.     for (p = MetaTokenNodes->next; p!=NULL; p=p->next)
  934.     {
  935.         set a,b;
  936.  
  937.         TokNode *q = (TokNode *)p->elem;
  938.         if ( q->wild_card )
  939.         {
  940.             q->tset = all_tokens;
  941.         }
  942.         else if ( q->tclass!=NULL )
  943.         {
  944.             if ( q->complement ) q->tset = set_dif(all_tokens, q->tclass->tset);
  945.             else q->tset = q->tclass->tset;
  946.         }
  947.         else if ( q->upper_range!=0 )
  948.         {
  949.             /* we have a range on our hands: make a set from q->token .. q->upper_range */
  950.             int i;
  951.             a = empty;
  952.             for (i=q->token; i<=(int)q->upper_range; i++) { set_orel(i, &a); }
  953.             q->tset = a;
  954.         }
  955.         /* at this point, it can only be a complemented single token */
  956.         else if ( q->complement )
  957.         {
  958.             a = set_of(q->token);
  959.             b = set_dif(all_tokens, a);
  960.             set_free(a);
  961.             q->tset=b;
  962.         }
  963.         else fatal("invalid meta token");
  964.     }
  965. }
  966.  
  967. char *
  968. #ifdef __STDC__
  969. OutMetaName(char *n)
  970. #else
  971. OutMetaName(n)
  972. char *n;
  973. #endif
  974. {
  975.     static char buf[MaxFileName+1];
  976.  
  977.     if ( strcmp(OutputDirectory,TopDirectory)==0 ) return n;
  978.     strcpy(buf, OutputDirectory);
  979.     if ( strcmp(&buf[strlen(buf) - 1], DirectorySymbol ) )
  980.         strcat(buf, DirectorySymbol);
  981.     strcat(buf, n);
  982.     return buf;
  983. }
  984.  
  985. static void
  986. #ifdef __STDC__
  987. ensure_no_C_file_collisions(char *class_c_file)
  988. #else
  989. ensure_no_C_file_collisions(class_c_file)
  990. char *class_c_file;
  991. #endif
  992. {
  993.     int i;
  994.  
  995.     for (i=0; i<NumFiles; i++)
  996.     {
  997. #ifdef PC
  998.         /* assume that file names are case insensitive */
  999.         if ( strcasecmp(outname(FileStr[i]), class_c_file)==0 )
  1000. #else
  1001.         if ( strcmp(outname(FileStr[i]), class_c_file)==0 )
  1002. #endif
  1003.         {
  1004.             fatal(eMsg1("class def output file conflicts with parser output file: %s",
  1005.                         outname(FileStr[i])));
  1006.         }
  1007.     }
  1008. }
  1009.  
  1010. void
  1011. #ifdef __STDC__
  1012. warnNoFL(char *err)
  1013. #else
  1014. warnNoFL(err)
  1015. char *err;
  1016. #endif
  1017. {
  1018.     fprintf(stderr, "warning: %s\n", err);
  1019. }
  1020.  
  1021. void
  1022. #ifdef __STDC__
  1023. warnFL(char *err,char *f,int l)
  1024. #else
  1025. warnFL(err,f,l)
  1026. char *f;
  1027. int l;
  1028. char *err;
  1029. #endif
  1030. {
  1031.     fprintf(stderr, ErrHdr, f, l);                        
  1032.     fprintf(stderr, " warning: %s\n", err);
  1033. }
  1034.  
  1035. void
  1036. #ifdef __STDC__
  1037. warn(char *err)                                                
  1038. #else
  1039. warn(err)                                                
  1040. char *err;
  1041. #endif
  1042. {
  1043.     /* back up the file number if we hit an error at the end of the last file */
  1044.     if ( CurFile >= NumFiles && CurFile >= 1 ) CurFile--;
  1045.     fprintf(stderr, ErrHdr, FileStr[CurFile], zzline);
  1046.     fprintf(stderr, " warning: %s\n", err);
  1047. }
  1048.  
  1049. void
  1050. #ifdef __STDC__
  1051. warnNoCR( char *err )
  1052. #else
  1053. warnNoCR( err )                                            
  1054. char *err;
  1055. #endif
  1056. {
  1057.     /* back up the file number if we hit an error at the end of the last file */
  1058.     if ( CurFile >= NumFiles && CurFile >= 1 ) CurFile--;
  1059.     fprintf(stderr, ErrHdr, FileStr[CurFile], zzline);
  1060.     fprintf(stderr, " warning: %s", err);
  1061. }
  1062.  
  1063. void
  1064. #ifdef __STDC__
  1065. errNoFL(char *err)
  1066. #else
  1067. errNoFL(err)
  1068. char *err;
  1069. #endif
  1070. {
  1071.     fprintf(stderr, "error: %s\n", err);
  1072. }
  1073.  
  1074. void
  1075. #ifdef __STDC__
  1076. errFL(char *err,char *f,int l)                                            
  1077. #else
  1078. errFL(err,f,l)                                            
  1079. char *err;
  1080. char *f;
  1081. int l;
  1082. #endif
  1083. {
  1084.     fprintf(stderr, ErrHdr, f, l);                        
  1085.     fprintf(stderr, " error: %s\n", err);
  1086. }
  1087.  
  1088. void
  1089. #ifdef __STDC__
  1090. err(char *err)                                                
  1091. #else
  1092. err(err)                                                
  1093. char *err;
  1094. #endif
  1095. {
  1096.     /* back up the file number if we hit an error at the end of the last file */
  1097.     if ( CurFile >= NumFiles && CurFile >= 1 ) CurFile--;
  1098.     fprintf(stderr, ErrHdr, FileStr[CurFile], zzline);
  1099.     fprintf(stderr, " error: %s\n", err);
  1100. }
  1101.  
  1102. void
  1103. #ifdef __STDC__
  1104. errNoCR( char *err )                                            
  1105. #else
  1106. errNoCR( err )                                            
  1107. char *err;
  1108. #endif
  1109. {
  1110.     /* back up the file number if we hit an error at the end of the last file */
  1111.     if ( CurFile >= NumFiles && CurFile >= 1 ) CurFile--;
  1112.     fprintf(stderr, ErrHdr, FileStr[CurFile], zzline);
  1113.     fprintf(stderr, " error: %s", err);
  1114. }
  1115.  
  1116. UserAction *
  1117. #ifdef __STDC__
  1118. newUserAction(char *s)
  1119. #else
  1120. newUserAction(s)
  1121. char *s;
  1122. #endif
  1123. {
  1124.     UserAction *ua = (UserAction *) calloc(1, sizeof(UserAction));
  1125.     require(ua!=NULL, "cannot allocate UserAction");
  1126.  
  1127.     ua->action = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));
  1128.     strcpy(ua->action, s);
  1129.     return ua;
  1130. }
  1131.